<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML
><HEAD
><TITLE
>Bash, version 4</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK
REL="HOME"
TITLE="Advanced Bash-Scripting Guide"
HREF="index.html"><LINK
REL="UP"
TITLE="Bash, versions 2, 3, and 4"
HREF="bash2.html"><LINK
REL="PREVIOUS"
TITLE="Bash, version 3"
HREF="bashver3.html"><LINK
REL="NEXT"
TITLE="Endnotes"
HREF="endnotes.html"></HEAD
><BODY
CLASS="SECT1"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Advanced Bash-Scripting Guide: </TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="bashver3.html"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Chapter 37. Bash, versions 2, 3, and 4</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="endnotes.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECT1"
><H1
CLASS="SECT1"
><A
NAME="BASHVER4"
></A
>37.3. Bash, version 4</H1
><P
><A
NAME="BASH4REF"
></A
></P
><P
>Chet Ramey announced Version 4 of Bash on the 20th
        of February, 2009. This release has a number of significant
	new features, as well as some important bugfixes.</P
><P
>Among the new goodies:</P
><P
></P
><UL
><LI
><P
><A
NAME="ASSOCARR"
></A
>Associative arrays.
                  <A
NAME="AEN21025"
HREF="#FTN.AEN21025"
><SPAN
CLASS="footnote"
>[1]</SPAN
></A
>
                </P
><TABLE
CLASS="SIDEBAR"
BORDER="1"
CELLPADDING="5"
><TR
><TD
><DIV
CLASS="SIDEBAR"
><A
NAME="AEN21029"
></A
><P
></P
><P
>An <I
CLASS="FIRSTTERM"
>associative</I
> array can
        be thought of as a set of two linked arrays -- one holding
        the <I
CLASS="FIRSTTERM"
>data</I
>, and the other the
        <I
CLASS="FIRSTTERM"
>keys</I
> that index the individual elements
	of the <I
CLASS="FIRSTTERM"
>data</I
> array.</P
><P
></P
></DIV
></TD
></TR
></TABLE
><DIV
CLASS="EXAMPLE"
><A
NAME="FETCHADDRESS"
></A
><P
><B
>Example 37-5. A simple address database</B
></P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>#!/bin/bash4
# fetch_address.sh

declare -A address
#       -A option declares associative array.

address[Charles]="414 W. 10th Ave., Baltimore, MD 21236"
address[John]="202 E. 3rd St., New York, NY 10009"
address[Wilma]="1854 Vermont Ave, Los Angeles, CA 90023"


echo "Charles's address is ${address[Charles]}."
# Charles's address is 414 W. 10th Ave., Baltimore, MD 21236.
echo "Wilma's address is ${address[Wilma]}."
# Wilma's address is 1854 Vermont Ave, Los Angeles, CA 90023.
echo "John's address is ${address[John]}."
# John's address is 202 E. 3rd St., New York, NY 10009.

echo

echo "${!address[*]}"   # The array indices ...
# Charles John Wilma</PRE
></FONT
></TD
></TR
></TABLE
></DIV
><DIV
CLASS="EXAMPLE"
><A
NAME="FETCHADDRESS2"
></A
><P
><B
>Example 37-6. A somewhat more elaborate address database</B
></P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>#!/bin/bash4
# fetch_address-2.sh
# A more elaborate version of fetch_address.sh.

SUCCESS=0
E_DB=99    # Error code for missing entry.

declare -A address
#       -A option declares associative array.


store_address ()
{
  address[$1]="$2"
  return $?
}


fetch_address ()
{
  if [[ -z "${address[$1]}" ]]
  then
    echo "$1's address is not in database."
    return $E_DB
  fi

  echo "$1's address is ${address[$1]}."
  return $?
}


store_address "Lucas Fayne" "414 W. 13th Ave., Baltimore, MD 21236"
store_address "Arvid Boyce" "202 E. 3rd St., New York, NY 10009"
store_address "Velma Winston" "1854 Vermont Ave, Los Angeles, CA 90023"
#  Exercise:
#  Rewrite the above store_address calls to read data from a file,
#+ then assign field 1 to name, field 2 to address in the array.
#  Each line in the file would have a format corresponding to the above.
#  Use a while-read loop to read from file, sed or awk to parse the fields.

fetch_address "Lucas Fayne"
# Lucas Fayne's address is 414 W. 13th Ave., Baltimore, MD 21236.
fetch_address "Velma Winston"
# Velma Winston's address is 1854 Vermont Ave, Los Angeles, CA 90023.
fetch_address "Arvid Boyce"
# Arvid Boyce's address is 202 E. 3rd St., New York, NY 10009.
fetch_address "Bozo Bozeman"
# Bozo Bozeman's address is not in database.

exit $?   # In this case, exit code = 99, since that is function return.</PRE
></FONT
></TD
></TR
></TABLE
></DIV
><P
>See <A
HREF="contributed-scripts.html#SAMORSE"
>Example A-53</A
> for an interesting
            usage of an <I
CLASS="FIRSTTERM"
>associative array</I
>.</P
><DIV
CLASS="CAUTION"
><P
></P
><TABLE
CLASS="CAUTION"
WIDTH="90%"
BORDER="0"
><TR
><TD
WIDTH="25"
ALIGN="CENTER"
VALIGN="TOP"
><IMG
SRC="../images/caution.gif"
HSPACE="5"
ALT="Caution"></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
><P
>Elements of the <I
CLASS="FIRSTTERM"
>index</I
> array
          may include embedded <A
HREF="special-chars.html#WHITESPACEREF"
>space
          characters</A
>, or even leading and/or trailing space
          characters. However, index array elements containing
	  <EM
>only</EM
> <I
CLASS="FIRSTTERM"
>whitespace</I
>
	  are <EM
>not</EM
> permitted.</P
><P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>address[   ]="Blank"   # Error!</PRE
></FONT
></TD
></TR
></TABLE
>
  </P
></TD
></TR
></TABLE
></DIV
></LI
><LI
><P
><A
NAME="NCTERM"
></A
>Enhancements to the
            <A
HREF="testbranch.html#CASEESAC1"
>case</A
> construct:
            the <TT
CLASS="REPLACEABLE"
><I
>;;&#38;</I
></TT
> and
            <TT
CLASS="REPLACEABLE"
><I
>;&#38;</I
></TT
> terminators.</P
><DIV
CLASS="EXAMPLE"
><A
NAME="CASE4"
></A
><P
><B
>Example 37-7. Testing characters</B
></P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>#!/bin/bash4

test_char ()
{
  case "$1" in
    [[:print:]] )  echo "$1 is a printable character.";;&#38;       # |
    # The ;;&#38; terminator continues to the next pattern test.      |
    [[:alnum:]] )  echo "$1 is an alpha/numeric character.";;&#38;  # v
    [[:alpha:]] )  echo "$1 is an alphabetic character.";;&#38;     # v
    [[:lower:]] )  echo "$1 is a lowercase alphabetic character.";;&#38;
    [[:digit:]] )  echo "$1 is an numeric character.";&#38;         # |
    # The ;&#38; terminator executes the next statement ...         # |
    %%%@@@@@    )  echo "********************************";;    # v
#   ^^^^^^^^  ... even with a dummy pattern.
  esac
}

echo

test_char 3
# 3 is a printable character.
# 3 is an alpha/numeric character.
# 3 is an numeric character.
# ********************************
echo

test_char m
# m is a printable character.
# m is an alpha/numeric character.
# m is an alphabetic character.
# m is a lowercase alphabetic character.
echo

test_char /
# / is a printable character.

echo

# The ;;&#38; terminator can save complex if/then conditions.
# The ;&#38; is somewhat less useful.</PRE
></FONT
></TD
></TR
></TABLE
></DIV
></LI
><LI
><P
><A
NAME="COPROCREF"
></A
>The new <B
CLASS="COMMAND"
>coproc</B
>
            builtin enables two parallel <A
HREF="special-chars.html#PROCESSREF"
>processes</A
> to communicate and
            interact. As Chet Ramey states in the
            <A
HREF="biblio.html#BASHFAQ"
>Bash FAQ</A
>
  <A
NAME="AEN21068"
HREF="#FTN.AEN21068"
><SPAN
CLASS="footnote"
>[2]</SPAN
></A
>
      , ver. 4.01:
    </P
><A
NAME="AEN21070"
></A
><BLOCKQUOTE
CLASS="BLOCKQUOTE"
><P
CLASS="LITERALLAYOUT"
>&nbsp;&nbsp;&nbsp;&nbsp;There&nbsp;is&nbsp;a&nbsp;new&nbsp;'coproc'&nbsp;reserved&nbsp;word&nbsp;that&nbsp;specifies&nbsp;a&nbsp;coprocess:<br>
&nbsp;&nbsp;&nbsp;&nbsp;an&nbsp;asynchronous&nbsp;command&nbsp;run&nbsp;with&nbsp;two&nbsp;pipes&nbsp;connected&nbsp;to&nbsp;the&nbsp;creating<br>
&nbsp;&nbsp;&nbsp;&nbsp;shell.&nbsp;Coprocs&nbsp;can&nbsp;be&nbsp;named.&nbsp;The&nbsp;input&nbsp;and&nbsp;output&nbsp;file&nbsp;descriptors<br>
&nbsp;&nbsp;&nbsp;&nbsp;and&nbsp;the&nbsp;PID&nbsp;of&nbsp;the&nbsp;coprocess&nbsp;are&nbsp;available&nbsp;to&nbsp;the&nbsp;calling&nbsp;shell&nbsp;in<br>
&nbsp;&nbsp;&nbsp;&nbsp;variables&nbsp;with&nbsp;coproc-specific&nbsp;names.<br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;George&nbsp;Dimitriu&nbsp;explains,<br>
&nbsp;&nbsp;&nbsp;&nbsp;"...&nbsp;coproc&nbsp;...&nbsp;is&nbsp;a&nbsp;feature&nbsp;used&nbsp;in&nbsp;Bash&nbsp;process&nbsp;substitution,<br>
&nbsp;&nbsp;&nbsp;&nbsp;which&nbsp;now&nbsp;is&nbsp;made&nbsp;publicly&nbsp;available."<br>
&nbsp;&nbsp;&nbsp;&nbsp;This&nbsp;means&nbsp;it&nbsp;can&nbsp;be&nbsp;explicitly&nbsp;invoked&nbsp;in&nbsp;a&nbsp;script,&nbsp;rather&nbsp;than<br>
&nbsp;&nbsp;&nbsp;&nbsp;just&nbsp;being&nbsp;a&nbsp;behind-the-scenes&nbsp;mechanism&nbsp;used&nbsp;by&nbsp;Bash.<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</P
></BLOCKQUOTE
><P
>Coprocesses use <I
CLASS="FIRSTTERM"
>file descriptors</I
>.
      <A
HREF="io-redirection.html#FDREF2"
>File descriptors enable processes and
        pipes to communicate</A
>.</P
><P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>#!/bin/bash4
# A coprocess communicates with a while-read loop.


coproc { cat mx_data.txt; sleep 2; }
#                         ^^^^^^^
# Try running this without "sleep 2" and see what happens.

while read -u ${COPROC[0]} line    #  ${COPROC[0]} is the
do                                 #+ file descriptor of the coprocess.
  echo "$line" | sed -e 's/line/NOT-ORIGINAL-TEXT/'
done

kill $COPROC_PID                   #  No longer need the coprocess,
                                   #+ so kill its PID.</PRE
></FONT
></TD
></TR
></TABLE
></P
><P
>But, be careful!</P
><P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>#!/bin/bash4

echo; echo
a=aaa
b=bbb
c=ccc

coproc echo "one two three"
while read -u ${COPROC[0]} a b c;  #  Note that this loop
do                                 #+ runs in a subshell.
  echo "Inside while-read loop: ";
  echo "a = $a"; echo "b = $b"; echo "c = $c"
  echo "coproc file descriptor: ${COPROC[0]}"
done 

# a = one
# b = two
# c = three
# So far, so good, but ...

echo "-----------------"
echo "Outside while-read loop: "
echo "a = $a"  # a =
echo "b = $b"  # b =
echo "c = $c"  # c =
echo "coproc file descriptor: ${COPROC[0]}"
echo
#  The coproc is still running, but ...
#+ it still doesn't enable the parent process
#+ to "inherit" variables from the child process, the while-read loop.

#  Compare this to the "badread.sh" script.</PRE
></FONT
></TD
></TR
></TABLE
></P
><DIV
CLASS="CAUTION"
><P
></P
><TABLE
CLASS="CAUTION"
WIDTH="90%"
BORDER="0"
><TR
><TD
WIDTH="25"
ALIGN="CENTER"
VALIGN="TOP"
><IMG
SRC="../images/caution.gif"
HSPACE="5"
ALT="Caution"></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
><P
>The coprocess is <I
CLASS="FIRSTTERM"
>asynchronous</I
>,
        and this might cause a problem. It may terminate before another
        process has finished communicating with it.</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>#!/bin/bash4

coproc cpname { for i in {0..10}; do echo "index = $i"; done; }
#      ^^^^^^ This is a *named* coprocess.
read -u ${cpname[0]}
echo $REPLY         #  index = 0
echo ${COPROC[0]}   #+ No output ... the coprocess timed out
#  after the first loop iteration.



# However, George Dimitriu has a partial fix.

coproc cpname { for i in {0..10}; do echo "index = $i"; done; sleep 1;
echo hi &#62; myo; cat - &#62;&#62; myo; }
#       ^^^^^ This is a *named* coprocess.

echo "I am main"$'\04' &#62;&#38;${cpname[1]}
myfd=${cpname[0]}
echo myfd=$myfd

### while read -u $myfd
### do
###   echo $REPLY;
### done

echo $cpname_PID

#  Run this with and without the commented-out while-loop, and it is
#+ apparent that each process, the executing shell and the coprocess,
#+ waits for the other to finish writing in its own write-enabled pipe.</PRE
></FONT
></TD
></TR
></TABLE
></TD
></TR
></TABLE
></DIV
></LI
><LI
><P
><A
NAME="MAPFILEREF"
></A
>The new <B
CLASS="COMMAND"
>mapfile</B
>
      builtin makes it possible to load an array with the contents
      of a text file without using a loop or <A
HREF="arrays.html#ARRAYINITCS"
>command substitution</A
>.</P
><P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>#!/bin/bash4

mapfile Arr1 &#60; $0
# Same result as     Arr1=( $(cat $0) )
echo "${Arr1[@]}"  # Copies this entire script out to stdout.

echo "--"; echo

# But, not the same as   read -a   !!!
read -a Arr2 &#60; $0
echo "${Arr2[@]}"  # Reads only first line of script into the array.

exit</PRE
></FONT
></TD
></TR
></TABLE
></P
></LI
><LI
><P
>The <A
HREF="internal.html#READREF"
>read</A
> builtin got
	a minor facelift. The <TT
CLASS="OPTION"
>-t</TT
>
	<A
HREF="internal.html#READTIMED"
>timeout</A
> option now accepts
	(decimal) fractional values
	        <A
NAME="AEN21096"
HREF="#FTN.AEN21096"
><SPAN
CLASS="footnote"
>[3]</SPAN
></A
>
	and the <TT
CLASS="OPTION"
>-i</TT
> option
	permits preloading the edit buffer.
	        <A
NAME="AEN21101"
HREF="#FTN.AEN21101"
><SPAN
CLASS="footnote"
>[4]</SPAN
></A
>
        Unfortunately, these enhancements are still a work in progress
        and not (yet) usable in scripts.</P
></LI
><LI
><P
><A
NAME="CASEMODPARAMSUB"
></A
>
                   <A
HREF="parameter-substitution.html#PARAMSUBREF"
>Parameter substitution</A
>
        gets <I
CLASS="FIRSTTERM"
>case-modification</I
> operators.</P
><P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>#!/bin/bash4

var=veryMixedUpVariable
echo ${var}            # veryMixedUpVariable
echo ${var^}           # VeryMixedUpVariable
#         *              First char --&#62; uppercase.
echo ${var^^}          # VERYMIXEDUPVARIABLE
#         **             All chars  --&#62; uppercase.
echo ${var,}           # veryMixedUpVariable
#         *              First char --&#62; lowercase.
echo ${var,,}          # verymixedupvariable
#         **             All chars  --&#62; lowercase.</PRE
></FONT
></TD
></TR
></TABLE
></P
></LI
><LI
><P
><A
NAME="DECLARECASEMOD"
></A
></P
><P
>The <A
HREF="declareref.html"
>declare</A
> builtin now
        accepts the <TT
CLASS="OPTION"
>-l</TT
> <I
CLASS="FIRSTTERM"
>lowercase</I
>
        and <TT
CLASS="OPTION"
>-c</TT
> <I
CLASS="FIRSTTERM"
>capitalize</I
>
        options.</P
><P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>#!/bin/bash4

declare -l var1            # Will change to lowercase
var1=MixedCaseVARIABLE
echo "$var1"               # mixedcasevariable
# Same effect as             echo $var1 | tr A-Z a-z

declare -c var2            # Changes only initial char to uppercase.
var2=originally_lowercase
echo "$var2"               # Originally_lowercase
# NOT the same effect as     echo $var2 | tr a-z A-Z</PRE
></FONT
></TD
></TR
></TABLE
></P
></LI
><LI
><P
><A
NAME="BRACEEXPREF4"
></A
>
      <A
HREF="special-chars.html#BRACEEXPREF"
>Brace expansion</A
> has more options.</P
><P
><I
CLASS="FIRSTTERM"
>Increment/decrement</I
>, specified in the
        final term within braces.</P
><P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>#!/bin/bash4

echo {40..60..2}
# 40 42 44 46 48 50 52 54 56 58 60
# All the even numbers, between 40 and 60.

echo {60..40..2}
# 60 58 56 54 52 50 48 46 44 42 40
# All the even numbers, between 40 and 60, counting backwards.
# In effect, a decrement.
echo {60..40..-2}
# The same output. The minus sign is not necessary.

# But, what about letters and symbols?
echo {X..d}
# X Y Z [  ] ^ _ ` a b c d
# Does not echo the \ which escapes a space.</PRE
></FONT
></TD
></TR
></TABLE
></P
><P
><I
CLASS="FIRSTTERM"
>Zero-padding</I
>, specified in the
	     first term within braces, prefixes each term in the output
	     with the <EM
>same number</EM
> of zeroes.</P
><TABLE
BORDER="1"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="SCREEN"
><TT
CLASS="PROMPT"
>bash4$ </TT
><TT
CLASS="USERINPUT"
><B
>echo {010..15}</B
></TT
>
<TT
CLASS="COMPUTEROUTPUT"
>010 011 012 013 014 015</TT
>


<TT
CLASS="PROMPT"
>bash4$ </TT
><TT
CLASS="USERINPUT"
><B
>echo {000..10}</B
></TT
>
<TT
CLASS="COMPUTEROUTPUT"
>000 001 002 003 004 005 006 007 008 009 010</TT
>
      </PRE
></FONT
></TD
></TR
></TABLE
></LI
><LI
><P
><A
NAME="SUBSTREXTREF4"
></A
></P
><P
><A
HREF="bashver4.html#SUBSTREXTREF4"
><I
CLASS="FIRSTTERM"
>Substring
          extraction</I
> on <I
CLASS="FIRSTTERM"
>positional
	  parameters</I
></A
> now starts with <A
HREF="othertypesv.html#SCRNAMEPARAM"
>$0</A
> as the
	  <I
CLASS="FIRSTTERM"
>zero-index</I
>. (This corrects an
	  inconsistency in the treatment of positional parameters.)</P
><P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>#!/bin/bash
# show-params.bash
# Requires version 4+ of Bash.

# Invoke this scripts with at least one positional parameter.

E_BADPARAMS=99

if [ -z "$1" ]
then
  echo "Usage $0 param1 ..."
  exit $E_BADPARAMS
fi

echo ${@:0}

# bash3 show-params.bash4 one two three
# one two three

# bash4 show-params.bash4 one two three
# show-params.bash4 one two three

# $0                $1  $2  $3</PRE
></FONT
></TD
></TR
></TABLE
></P
></LI
><LI
><P
><A
NAME="GLOBSTARREF"
></A
>The new <SPAN
CLASS="TOKEN"
>**</SPAN
>
            <A
HREF="globbingref.html"
>globbing</A
> operator
	    matches filenames and directories
	    <A
HREF="localvar.html#RECURSIONREF0"
>recursively</A
>.</P
><P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>#!/bin/bash4
# filelist.bash4

shopt -s globstar  # Must enable globstar, otherwise ** doesn't work.
                   # The globstar shell option is new to version 4 of Bash.

echo "Using *"; echo
for filename in *
do
  echo "$filename"
done   # Lists only files in current directory ($PWD).

echo; echo "--------------"; echo

echo "Using **"
for filename in **
do
  echo "$filename"
done   # Lists complete file tree, recursively.

exit

Using *

allmyfiles
filelist.bash4

--------------

Using **

allmyfiles
allmyfiles/file.index.txt
allmyfiles/my_music
allmyfiles/my_music/me-singing-60s-folksongs.ogg
allmyfiles/my_music/me-singing-opera.ogg
allmyfiles/my_music/piano-lesson.1.ogg
allmyfiles/my_pictures
allmyfiles/my_pictures/at-beach-with-Jade.png
allmyfiles/my_pictures/picnic-with-Melissa.png
filelist.bash4</PRE
></FONT
></TD
></TR
></TABLE
></P
></LI
><LI
><P
>The new <A
HREF="internalvariables.html#BASHPIDREF"
>$BASHPID</A
>
        internal variable.</P
></LI
><LI
><P
><A
NAME="CNFH"
></A
></P
><P
>There is a new <A
HREF="internal.html#BUILTINREF"
>builtin</A
>
            error-handling function named
	    <B
CLASS="COMMAND"
>command_not_found_handle</B
>.</P
><P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>#!/bin/bash4

command_not_found_handle ()
{ # Accepts implicit parameters.
  echo "The following command is not valid: \""$1\"""
  echo "With the following argument(s): \""$2\"" \""$3\"""   # $4, $5 ...
} # $1, $2, etc. are not explicitly passed to the function.

bad_command arg1 arg2

# The following command is not valid: "bad_command"
# With the following argument(s): "arg1" "arg2"</PRE
></FONT
></TD
></TR
></TABLE
></P
></LI
></UL
><TABLE
CLASS="SIDEBAR"
BORDER="1"
CELLPADDING="5"
><TR
><TD
><DIV
CLASS="SIDEBAR"
><A
NAME="AEN21170"
></A
><P
></P
><P
><EM
>Editorial comment</EM
></P
><P
>Associative arrays? Coprocesses? Whatever happened
          to the lean and mean Bash we have come to know and love?
          Could it be suffering from (horrors!) <SPAN
CLASS="QUOTE"
>"feature
          creep"</SPAN
>? Or perhaps even Korn shell envy?</P
><P
><EM
>Note to Chet Ramey:</EM
> Please add only
          <EM
>essential</EM
> features in future Bash
	  releases -- perhaps <I
CLASS="FIRSTTERM"
>for-each</I
>
	  loops and support for multi-dimensional arrays.
	    <A
NAME="AEN21179"
HREF="#FTN.AEN21179"
><SPAN
CLASS="footnote"
>[5]</SPAN
></A
>
	  Most Bash users won't need, won't use, and likely won't greatly
	  appreciate complex <SPAN
CLASS="QUOTE"
>"features"</SPAN
> like built-in
	  debuggers, Perl interfaces, and bolt-on rocket boosters.</P
><P
></P
></DIV
></TD
></TR
></TABLE
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="AEN21183"
></A
>37.3.1. Bash, version 4.1</H2
><P
><A
NAME="BASH41"
></A
>Version 4.1 of Bash, released in May,
	   2010, was primarily a bugfix update.</P
><P
></P
><UL
><LI
><P
>The <A
HREF="internal.html#PRINTFREF"
>printf</A
> command
        now accepts a <TT
CLASS="OPTION"
>-v</TT
> option for setting <A
HREF="arrays.html#ARRAYREF"
>array</A
> indices.</P
></LI
><LI
><P
>Within <A
HREF="testconstructs.html#DBLBRACKETS"
>double brackets</A
>,
        the <B
CLASS="COMMAND"
>&#62;</B
> and <B
CLASS="COMMAND"
>&#60;</B
>
        string comparison operators now conform to the <A
HREF="localization.html#LOCALEREF"
>locale</A
>. Since the locale setting may
        affect the sorting order of string expressions, this
	has side-effects on comparison tests within
        <EM
>[[ ... ]]</EM
> expressions.</P
></LI
><LI
><P
>The <A
HREF="internal.html#READREF"
>read</A
> builtin
        now takes a <TT
CLASS="OPTION"
>-N</TT
> option (<I
CLASS="FIRSTTERM"
>read -N
        chars</I
>), which causes the <I
CLASS="FIRSTTERM"
>read</I
>
        to terminate after <I
CLASS="FIRSTTERM"
>chars</I
>
        characters.</P
><DIV
CLASS="EXAMPLE"
><A
NAME="READN"
></A
><P
><B
>Example 37-8. Reading N characters</B
></P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>#!/bin/bash
# Requires Bash version -ge 4.1 ...

num_chars=61

read -N $num_chars var &#60; $0   # Read first 61 characters of script!
echo "$var"
exit

####### Output of Script #######

#!/bin/bash
# Requires Bash version -ge 4.1 ...

num_chars=61</PRE
></FONT
></TD
></TR
></TABLE
></DIV
></LI
><LI
><P
><A
HREF="here-docs.html#HEREDOCREF"
>Here documents</A
>
	      embedded in <A
HREF="varassignment.html#COMMANDSUBREF0"
>              <TT
CLASS="USERINPUT"
><B
>$( ... )</B
></TT
> command substitution</A
>
	      constructs may terminate with a simple
	      <B
CLASS="COMMAND"
>)</B
>.</P
><DIV
CLASS="EXAMPLE"
><A
NAME="HERECOMMSUB"
></A
><P
><B
>Example 37-9. Using a <I
CLASS="FIRSTTERM"
>here document</I
>
                       to set a variable</B
></P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>#!/bin/bash
# here-commsub.sh
# Requires Bash version -ge 4.1 ...

multi_line_var=$( cat &#60;&#60;ENDxxx
------------------------------
This is line 1 of the variable
This is line 2 of the variable
This is line 3 of the variable
------------------------------
ENDxxx)

#  Rather than what Bash 4.0 requires:
#+ that the terminating limit string and
#+ the terminating close-parenthesis be on separate lines.

# ENDxxx
# )


echo "$multi_line_var"

#  Bash still emits a warning, though.
#  warning: here-document at line 10 delimited
#+ by end-of-file (wanted `ENDxxx')</PRE
></FONT
></TD
></TR
></TABLE
></DIV
></LI
></UL
></DIV
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="AEN21220"
></A
>37.3.2. Bash, version 4.2</H2
><P
><A
NAME="BASH42"
></A
>Version 4.2 of Bash, released
	   in February, 2011, contains a number of new features and
	   enhancements, in addition to bugfixes.</P
><P
></P
><UL
><LI
><P
>Bash now supports the the
		<TT
CLASS="REPLACEABLE"
><I
>\u</I
></TT
>
		and <TT
CLASS="REPLACEABLE"
><I
>\U</I
></TT
>
		<I
CLASS="FIRSTTERM"
>Unicode</I
> escape.</P
><P
><A
NAME="UNICODEREF"
></A
></P
><TABLE
CLASS="SIDEBAR"
BORDER="1"
CELLPADDING="5"
><TR
><TD
><DIV
CLASS="SIDEBAR"
><A
NAME="AEN21232"
></A
><P
></P
><P
>Unicode is a cross-platform standard for encoding
          into numerical values letters and graphic symbols.
          This permits representing and displaying characters
          in foreign alphabets and unusual fonts.</P
><P
></P
></DIV
></TD
></TR
></TABLE
><P
><A
NAME="UNICODEREF2"
></A
></P
><P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>echo -e '\u2630'   # Horizontal triple bar character.
# Equivalent to the more roundabout:
echo -e "\xE2\x98\xB0"
                   # Recognized by earlier Bash versions.

echo -e '\u220F'   # PI (Greek letter and mathematical symbol)
echo -e '\u0416'   # Capital "ZHE" (Cyrillic letter)
echo -e '\u2708'   # Airplane (Dingbat font) symbol
echo -e '\u2622'   # Radioactivity trefoil

echo -e "The amplifier circuit requires a 100 \u2126 pull-up resistor."


unicode_var='\u2640'
echo -e $unicode_var      # Female symbol
printf "$unicode_var \n"  # Female symbol, with newline


#  And for something a bit more elaborate . . .

#  We can store Unicode symbols in an associative array,
#+ then retrieve them by name.
#  Run this in a gnome-terminal or a terminal with a large, bold font
#+ for better legibility.

declare -A symbol  # Associative array.

symbol[script_E]='\u2130'
symbol[script_F]='\u2131'
symbol[script_J]='\u2110'
symbol[script_M]='\u2133'
symbol[Rx]='\u211E'
symbol[TEL]='\u2121'
symbol[FAX]='\u213B'
symbol[care_of]='\u2105'
symbol[account]='\u2100'
symbol[trademark]='\u2122'


echo -ne "${symbol[script_E]}   "
echo -ne "${symbol[script_F]}   "
echo -ne "${symbol[script_J]}   "
echo -ne "${symbol[script_M]}   "
echo -ne "${symbol[Rx]}   "
echo -ne "${symbol[TEL]}   "
echo -ne "${symbol[FAX]}   "
echo -ne "${symbol[care_of]}   "
echo -ne "${symbol[account]}   "
echo -ne "${symbol[trademark]}   "
echo</PRE
></FONT
></TD
></TR
></TABLE
></P
><DIV
CLASS="NOTE"
><P
></P
><TABLE
CLASS="NOTE"
WIDTH="90%"
BORDER="0"
><TR
><TD
WIDTH="25"
ALIGN="CENTER"
VALIGN="TOP"
><IMG
SRC="../images/note.gif"
HSPACE="5"
ALT="Note"></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
><P
>The above example uses the
          <A
HREF="escapingsection.html#STRQ"
><B
CLASS="COMMAND"
>$' ... '</B
></A
>
          <I
CLASS="FIRSTTERM"
>string-expansion</I
> construct.</P
></TD
></TR
></TABLE
></DIV
></LI
><LI
><P
><A
NAME="LASTPIPEREF"
></A
></P
><P
>When the <TT
CLASS="REPLACEABLE"
><I
>lastpipe</I
></TT
> shell option
          is set, the last command in a <A
HREF="special-chars.html#PIPEREF"
>pipe</A
> <EM
>doesn't run in a
	  subshell</EM
>.</P
><DIV
CLASS="EXAMPLE"
><A
NAME="LASTPIPEOPT"
></A
><P
><B
>Example 37-10. Piping input to a <A
HREF="internal.html#READREF"
>read</A
></B
></P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>#!/bin/bash
# lastpipe-option.sh

line=''                   # Null value.
echo "\$line = "$line""   # $line =

echo

shopt -s lastpipe         # Error on Bash version -lt 4.2.
echo "Exit status of attempting to set \"lastpipe\" option is $?"
#     1 if Bash version -lt 4.2, 0 otherwise.

echo

head -1 $0 | read line    # Pipe the first line of the script to read.
#            ^^^^^^^^^      Not in a subshell!!!

echo "\$line = "$line""
# Older Bash releases       $line =
# Bash version 4.2          $line = #!/bin/bash</PRE
></FONT
></TD
></TR
></TABLE
></DIV
><P
>This option offers possible <SPAN
CLASS="QUOTE"
>"fixups"</SPAN
>
		    for these example scripts:
		    <A
HREF="gotchas.html#BADREAD"
>Example 34-3</A
> and
                    <A
HREF="internal.html#READPIPE"
>Example 15-8</A
>.</P
></LI
><LI
><P
>Negative <A
HREF="arrays.html#ARRAYREF"
>array</A
> indices
           permit counting backwards from the end of an array.</P
><DIV
CLASS="EXAMPLE"
><A
NAME="NEGARRAY"
></A
><P
><B
>Example 37-11. Negative array indices</B
></P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>#!/bin/bash
# neg-array.sh
# Requires Bash, version -ge 4.2.

array=( zero one two three four five )   # Six-element array.
#         0    1   2    3    4    5
#        -6   -5  -4   -3   -2   -1

# Negative array indices now permitted.
echo ${array[-1]}   # five
echo ${array[-2]}   # four
# ...
echo ${array[-6]}   # zero
# Negative array indices count backward from the last element+1.

# But, you cannot index past the beginning of the array.
echo ${array[-7]}   # array: bad array subscript


# So, what is this new feature good for?

echo "The last element in the array is "${array[-1]}""
# Which is quite a bit more straightforward than:
echo "The last element in the array is "${array[${#array[*]}-1]}""
echo

# And ...

index=0
let "neg_element_count = 0 - ${#array[*]}"
# Number of elements, converted to a negative number.

while [ $index -gt $neg_element_count ]; do
  ((index--)); echo -n "${array[index]} "
done  # Lists the elements in the array, backwards.
      # We have just simulated the "tac" command on this array.

echo

# See also neg-offset.sh.</PRE
></FONT
></TD
></TR
></TABLE
></DIV
></LI
><LI
><P
><A
HREF="string-manipulation.html#SUBSTREXTR01"
>Substring extraction</A
>
           uses a negative <I
CLASS="FIRSTTERM"
>length</I
> parameter to
           specify an offset from the <I
CLASS="FIRSTTERM"
>end</I
> of the
           target string.</P
><DIV
CLASS="EXAMPLE"
><A
NAME="NEGOFFSET"
></A
><P
><B
>Example 37-12. Negative parameter in string-extraction
                      construct</B
></P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>#!/bin/bash
# Bash, version -ge 4.2
# Negative length-index in substring extraction.
# Important: It changes the interpretation of this construct!

stringZ=abcABC123ABCabc

echo ${stringZ}                              # abcABC123ABCabc
#                   Position within string:    0123456789.....
echo ${stringZ:2:3}                          #   cAB
#  Count 2 chars forward from string beginning, and extract 3 chars.
#  ${string:position:length}

#  So far, nothing new, but now ...

                                             # abcABC123ABCabc
#                   Position within string:    0123....6543210
echo ${stringZ:3:-6}                         #    ABC123
#                ^
#  Index 3 chars forward from beginning and 6 chars backward from end,
#+ and extract everything in between.
#  ${string:offset-from-front:offset-from-end}
#  When the "length" parameter is negative, 
#+ it serves as an offset-from-end parameter.

#  See also neg-array.sh.</PRE
></FONT
></TD
></TR
></TABLE
></DIV
></LI
></UL
></DIV
></DIV
><H3
CLASS="FOOTNOTES"
>Notes</H3
><TABLE
BORDER="0"
CLASS="FOOTNOTES"
WIDTH="100%"
><TR
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="5%"
><A
NAME="FTN.AEN21025"
HREF="bashver4.html#AEN21025"
><SPAN
CLASS="footnote"
>[1]</SPAN
></A
></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="95%"
><P
>To be more specific, Bash 4+ has
                  <EM
>limited</EM
> support for associative
		  arrays. It's a bare-bones implementation,
		  and it lacks the much of the functionality of such
		  arrays in other programming languages. Note, however,
		  that <A
HREF="optimizations.html#ASSOCARRTST"
>associative arrays in
		  Bash seem to execute faster and more efficiently than
		  numerically-indexed arrays</A
>.</P
></TD
></TR
><TR
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="5%"
><A
NAME="FTN.AEN21068"
HREF="bashver4.html#AEN21068"
><SPAN
CLASS="footnote"
>[2]</SPAN
></A
></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="95%"
><P
>Copyright 1995-2009 by Chester Ramey.</P
></TD
></TR
><TR
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="5%"
><A
NAME="FTN.AEN21096"
HREF="bashver4.html#AEN21096"
><SPAN
CLASS="footnote"
>[3]</SPAN
></A
></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="95%"
><P
>This only works with <A
HREF="special-chars.html#PIPEREF"
>pipes</A
> and certain other
                <I
CLASS="FIRSTTERM"
>special</I
> files.</P
></TD
></TR
><TR
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="5%"
><A
NAME="FTN.AEN21101"
HREF="bashver4.html#AEN21101"
><SPAN
CLASS="footnote"
>[4]</SPAN
></A
></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="95%"
><P
>But only in conjunction with
                <A
HREF="internal.html#READLINEREF"
>readline</A
>, i.e.,
                from the command-line.</P
></TD
></TR
><TR
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="5%"
><A
NAME="FTN.AEN21179"
HREF="bashver4.html#AEN21179"
><SPAN
CLASS="footnote"
>[5]</SPAN
></A
></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="95%"
><P
>And while you're at it, consider fixing
              the notorious <A
HREF="internal.html#PIPEREADREF0"
>piped read</A
>
	      problem.</P
></TD
></TR
></TABLE
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="bashver3.html"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="index.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="endnotes.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Bash, version 3</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="bash2.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Endnotes</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>